<?php

namespace App\Tools;

use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use Illuminate\Support\Facades\Redis;

class Sms
{

    /**
     * 获取配置文件
     * @return array
     */
    private static function getConfig()
    {
        # 使用RAM账号,需要授权
//        $sign   = '益恩喜';
//        $key    = 'LTAI4GCAXZ1zZu45HUDmo4C9';
//        $secret = 'uOgi13U2mxfO83yS6soNuWagfW8yey';
        $sign = '亿恩鑫';
        $key = 'LTAI5tL4U3giDQXosjhit8s7';
        $secret = 'W6C58jyj4nxYIBiBchvzwoauIROEqJ';
        return compact('key', 'secret', 'sign');
    }

    /**
     * 发送短信 验证码
     * @param $mobile
     * @param $template
     * @param $param
     * @return mixed
     * @throws ClientException
     */
    public static function sendSms($mobile, $template, $param)
    {
        $config = self::getConfig();

        AlibabaCloud::accessKeyClient($config['key'], $config['secret'])
            ->regionId('cn-hangzhou')                           # 指定请求的地域
            ->asDefaultClient();

        try {
            $result = AlibabaCloud::rpc()
                ->product('Dysmsapi')                             # 指定产品
                // ->scheme('https')                                      # https | http
                ->version('2017-05-25')                           # 指定产品版本
                ->action('SendSms')                                # 指定产品接口
                ->method('POST')                                  # 指定请求方式
                ->host('dysmsapi.aliyuncs.com')                     # 指定域名则不会寻址，如认证方式为Bearer Token的服务则需要指定。
                ->options([
                    'query' => [
                        'PhoneNumbers' => $mobile,              # 手机号
                        'SignName' => $config['sign'],          # 签名
                        'TemplateCode' => $template,            # 模板
                        'TemplateParam' => json_encode($param)  # 模板参数
                    ],
                ])
                ->request();
            $res = $result->toArray();
            if ($res['Code'] != "OK") {
                return errorMsg($result['Message']);
            }
        } catch (ClientException $e) {
            return errorMsg($e->getErrorMessage());
        } catch (ServerException $e) {
            return errorMsg($e->getErrorMessage());
        } catch (\Exception $e) {
            return errorMsg($e->getMessage());
        }
    }

    /**
     * 发送短信验证码
     * @param $mobile
     * @param $ip
     * @return mixed
     * @throws \AlibabaCloud\Client\Exception\ClientException
     */
    public static function sendCode($mobile, $ip)
    {
        # 验证参数
        if (!preg_match('/^1[345789][0-9]{9}$/', $mobile)) {
            return errorMsg('手机号格式不正确');
        }

        # 发送短信风控
        # 同一IP同一手机号，30分钟内发送次数超过10次，此IP拉黑2小时
        $ipKey = 'SMS:' . $ip . ':' . $mobile;
        $count = Redis::GET($ipKey);
        if ($count > 9) {
            # IP拉黑2小时
            Redis::EXPIRE($ipKey, 2 * 60 * 60);
            return errorMsg('发送过于频繁');
        }

        # 同一手机号，60秒（前端展示的倒计时）内只能发送一次
        $mobileKey = 'SMS:' . $mobile;
        $value = Redis::GET($mobileKey);
        if ($value) {
            return errorMsg('发送过于频繁，请稍后重试');
        }

        # 验证码
        $code = rand(100000, 999999);
        $data = ['validatingCode' => $code];

        # 发送
//        self::sendSms($mobile, 'SMS_190267316', $data);
        self::sendSms($mobile, 'SMS_216841164', $data);
        # 发送成功，记录数据
        Redis::INCR($ipKey);
        if (!$count) {
            # 有效期30分钟
            Redis::EXPIRE($ipKey, 30 * 60);
        }
        Redis::SET($mobileKey, $code);
        Redis::EXPIRE($mobileKey, 60);
    }
}
